#include <iostream>
#include <sys/timeb.h>
#include <time.h>

#include "CServiceProxy.h"

#include "space/CMessage.h"
#include "space/CKeyValue.h"

//#ifndef INFINITE
//#define INFINITE
//#endif

using namespace std;

int getRandom()
{
	struct timeb itb;
	struct tm *lt;
	ftime(&itb);
	lt = localtime(&itb.time);
	srand(lt->tm_sec+itb.millitm);

	int random_port = rand();

	return random_port;
}

int main(int argc, char **argv)
{
	if(argc<2) {
		cout << "==============================================" << endl;
		cout << "For CGI Server : " << argv[0] << endl;
		cout << "For Stand-alone Server : " << argv[0] << " <port>" << endl;
		cout << "==============================================" << endl;
	}

	cout << endl << endl;
	cout << "=========================================================" << endl;
	cout << "[test]Space" << endl;
	cout << "=========================================================" << endl;
	
	CServiceProxy proxy;
        if(argc>1) proxy.connect("localhost", atoi(argv[1]));

	for(long num=0;;num++) {
		cout << "============= " << num << " ============" << endl;

		char rand_num[256];
		sprintf(rand_num,"%d",getRandom());

		// write
		CObjectArray *pobjs = new CObjectArray(6);
		(*pobjs)[0] = new cube__CKeyValue();
		(*pobjs)[1] = new cube__CKeyValue();
		(*pobjs)[2] = new cube__CKeyValue();
		(*pobjs)[3] = new cube__CKeyValue();
		(*pobjs)[4] = new cube__CKeyValue();
		(*pobjs)[5] = new cube__CKeyValue();
		dynamic_cast<cube__CKeyValue *>((*pobjs)[0])->set("command", "write");
		dynamic_cast<cube__CKeyValue *>((*pobjs)[1])->set(rand_num, "[message1]this is the 1st message");
		dynamic_cast<cube__CKeyValue *>((*pobjs)[2])->set(rand_num, "[message2]this is the 2nd message");
		dynamic_cast<cube__CKeyValue *>((*pobjs)[3])->set(rand_num, "[message3]this is the 3rd message");
		dynamic_cast<cube__CKeyValue *>((*pobjs)[4])->set(rand_num, "[message4]this is the 4th message");
		dynamic_cast<cube__CKeyValue *>((*pobjs)[5])->set(rand_num, "[message5]this is the 5th message");

		cout << "[write] 5 messages" << endl;

		cube__CService space_service;
		space_service.service("sample.space.service");

		struct cube__invokeResponse res3;

		// invoke space service : write
		if(proxy.invoke(&space_service, pobjs, res3)!=SOAP_OK) {
			soap_print_fault(proxy.soap(), stderr);

			delete (*pobjs)[0];
			delete (*pobjs)[1];
			delete (*pobjs)[2];
			delete (*pobjs)[3];
			delete (*pobjs)[4];
			delete (*pobjs)[5];
			delete pobjs;

			return -1;
		}

		cout << "-------------- sample.space.service -------------" << endl;
		cout << "response size = " << ((CObjectArray *)res3.out)->__size << endl;

		for(int i=0;i<((CObjectArray *)res3.out)->__size;i++) {
			cout << "[" << i << "]"; 
			dynamic_cast<cube__CKeyValue *>(((CObjectArray *)res3.out)->__ptr[i])->print();
		}

		delete (*pobjs)[0];
		delete (*pobjs)[1];
		delete (*pobjs)[2];
		delete (*pobjs)[3];
		delete (*pobjs)[4];
		delete (*pobjs)[5];
		delete pobjs;

		cout << endl << endl;

		// read
		pobjs = new CObjectArray(1);
		(*pobjs)[0] = new cube__CKeyValue();
		dynamic_cast<cube__CKeyValue *>((*pobjs)[0])->set("command", "read");

		cout << "[read] a message" << endl;

		struct cube__invokeResponse res5;

		// invoke space service
		if(proxy.invoke(&space_service, pobjs, res5)!=SOAP_OK) {
			soap_print_fault(proxy.soap(), stderr);

			delete (*pobjs)[0];
			delete pobjs;

			return -1;
		}

		cout << "-------------- sample.space.service -------------" << endl;
		cout << "response size = " << ((CObjectArray *)res5.out)->__size << endl;

		for(int i=0;i<((CObjectArray *)res5.out)->__size;i++) {
			cout << "[" << i << "]";
			dynamic_cast<cube__CKeyValue *>(((CObjectArray *)res5.out)->__ptr[i])->print();
		}

		delete (*pobjs)[0];
		delete pobjs;


		cout << endl << endl;


		// take
		pobjs = new CObjectArray(1);
		(*pobjs)[0] = new cube__CKeyValue();
		dynamic_cast<cube__CKeyValue *>((*pobjs)[0])->set("command", "take");

		cout << "[take] all messages" << endl;

		struct cube__invokeResponse res4;

		// invoke space service
		if(proxy.invoke(&space_service, pobjs, res4)!=SOAP_OK) {
			soap_print_fault(proxy.soap(), stderr);

			delete (*pobjs)[0];
			delete pobjs;

			return -1;
		}

		cout << "-------------- sample.space.service -------------" << endl;
		cout << "response size = " << ((CObjectArray *)res4.out)->__size << endl;

		for(int i=0;i<((CObjectArray *)res4.out)->__size;i++) {
			cout << "[" << i << "]";
			dynamic_cast<cube__CKeyValue *>(((CObjectArray *)res4.out)->__ptr[i])->print();
		}

		delete (*pobjs)[0];
		delete pobjs;

		// clear memory
		proxy.gc();
	}

        return 0;
}
